package org.sinrel.engine.library.cryption; import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.StringUtils; import org.apache.commons.codec.digest.DigestUtils; /** * Класс для шифрования строк алгоритмом AES-128 */ public final class AES { private static byte[] key = MD5.md5( StringUtils.getBytesUtf8( "sle" ) ); /** * Превращает текст в ключ и устанавливает его для методов <br> * {@link AESUtils#encryptAESBase64String(String)} <br> * и {@link AESUtils#decryptAESBase64String(String)} * * @param key * Строка с ключом */ public static void setKey( String key ) { if( key == null ) throw new NullPointerException( "Ключ не может быть null" ); AES.key = DigestUtils.md5( StringUtils.getBytesUtf8( key ) ); } /** * Шифрует строку по алгоритму AES и кодирует ее в Base64 <br> * С использованием ранее установленного через метод {@link AES#setKey(String) } ключа * * @param text * Текст для шифрования * @return Зашифрованный в AES и закодированный в Base64 текст * @throws GeneralSecurityException */ public static String encrypt(String text) throws GeneralSecurityException { return encryptAESBase64String(text, key); } /** * Декодирует строку из Base64 и дешифрует по алгоритму AES <br> * С использованием ранее установленного через метод {@link AES#setKey(String) } ключа * * @param b64_encrypted * Шифрованные данные * @return Дешифрованную строку * @throws GeneralSecurityException */ public static String decrypt(String b64_encrypted) throws GeneralSecurityException { return decryptAESBase64String(b64_encrypted, key); } /** * Шифрует строку по алгоритму AES и кодирует ее в Base64 * * @param text * Текст для шифрования * @param key * Cтрока с ключом * @return Зашифрованный в AES и закодированный в Base64 текст * @throws GeneralSecurityException */ public static String encrypt( String text, String key ) throws GeneralSecurityException { return encryptAESBase64String( text, MD5.md5( StringUtils.getBytesUtf8( key ) ) ); } /** * Декодирует строку из Base64 и дешифрует по алгоритму AES * * @param b64_encrypted * Шифрованные данные * @param key * Cтрока с ключом * @return Дешифрованную строку * @throws GeneralSecurityException */ public static String decrypt( String b64_encrypted, String key ) throws GeneralSecurityException { return decrypt( b64_encrypted, StringUtils.getBytesUtf8(key) ); } /** * Шифрует строку по алгоритму AES и кодирует ее в Base64 * * @param text * Текст для шифрования * @param key * Массив байтов с ключом * @return Зашифрованный в AES и закодированный в Base64 текст * @throws GeneralSecurityException */ public static String encrypt(String text, byte[] key) throws GeneralSecurityException { return encryptAESBase64String(text, makeKey(key)); } /** * Декодирует строку из Base64 и дешифрует по алгоритму AES * * @param b64_encrypted * Шифрованные данные * @param key * Массив байтов с ключом * @return Дешифрованную строку * @throws GeneralSecurityException */ public static String decrypt(String b64_encrypted, byte[] key) throws GeneralSecurityException { return decryptAESBase64String(b64_encrypted, makeKey(key)); } /** * Генерирует ключ для алгоритма AES * * @return Сгенерированный ключ */ public static byte[] generateKey() { byte[] key = null; try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128); SecretKey skey = kgen.generateKey(); key = skey.getEncoded(); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); } return key; } // Private methods public static String encryptAESBase64String(String text, byte[] key) throws GeneralSecurityException { SecretKeySpec keyspec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); cipher.init(Cipher.ENCRYPT_MODE, keyspec, getIVSpec()); byte[] padded = padByteArray(StringUtils.getBytesUtf8(text)); byte[] encrypted = cipher.doFinal(padded); return Base64.encodeBase64URLSafeString(encrypted); } public static String decryptAESBase64String(String b64_encrypted, byte[] key) throws GeneralSecurityException { SecretKeySpec keyspec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, keyspec, getIVSpec()); byte[] decrypted = cipher.doFinal(Base64.decodeBase64(b64_encrypted)); return StringUtils.newStringUtf8(decrypted).replace("\0", ""); } private static IvParameterSpec getIVSpec() { return new IvParameterSpec(StringUtils.getBytesUtf8("%jUS*(Aol(-y)lC/")); } private static byte[] padByteArray(byte[] source) { int size = 16; // Key length int x = source.length / size + 1; return Arrays.copyOf(source, size * x); } private static byte[] makeKey(byte[] bytes) { return MD5.md5(bytes); } }